package cn.xiaojf.util;

import java.io.File;
import java.util.UUID;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import org.apache.commons.lang3.StringUtils;

/**
 * office 文档转换成pdf工具类，通过jacob调用wps转换文档
 * @author xiaojf 2017/12/2 8:29
 */
public class OfficeConverterUtil {

    private static final int WDFO_RMATPDF = 17;
    private static final int XLTYPE_PDF = 0;
    private static final int PPT_SAVEAS_PDF = 32;
    public static final int WORD_HTML = 8;
    public static final int WORD_TXT = 7;
    public static final int EXCEL_HTML = 44;
    public static final int PPT_SAVEAS_JPG = 17;
    // private static final int msoTrue = -1;
    // private static final int msofalse = 0;

    private static ActiveXComponent wordApp = null;
    private static ActiveXComponent excelApp = null;
    private static ActiveXComponent pptApp = null;
    private static ActiveXComponent ppApp = null;

    static {
        wordApp = new ActiveXComponent("Word.Application");
        wordApp.setProperty("Visible", new Variant(false));

        excelApp = new ActiveXComponent("Excel.Application");
        excelApp.setProperty("Visible", false);

        pptApp = new ActiveXComponent("KWPP.Application");
        ppApp = new ActiveXComponent("PowerPoint.Application");
    }

    /**
     * office文件转换成pdf，根据后缀名识别转换类型
     * @param inputFilePath 输入文件绝对路径
     * @param pdfPath 输出文件绝对路径
     * @return 转换是否成功，true 成功，false 不成功
     * @author xiaojf 2017/12/2 8:30
     */
    public static boolean officeFileConverterToPdf(String inputFilePath, String pdfPath) {
        if (StringUtils.isBlank(inputFilePath) || StringUtils.isBlank(pdfPath) || StringUtils.isBlank(getFileSufix(inputFilePath))) {
            return false;
        }

        String suffix = getFileSufix(inputFilePath);

        File file = new File(inputFilePath);
        if (!file.exists()) {
            return false;
        }

        // PDF如果不存在则创建文件夹
        file = new File(getFilePath(pdfPath));
        if (!file.exists()) {
            file.mkdir();
        }

        // 如果输入的路径为PDF 则生成失败
        if (suffix.equals("pdf")) {
            System.out.println("PDF not need to convert!");
            return false;
        }

        if (suffix.equals("doc") || suffix.equals("docx") || suffix.equals("txt")) {
            return wordToPDF(inputFilePath, pdfPath);
        } else if (suffix.equals("xls") || suffix.equals("xlsx")) {
            return excelToPdf(inputFilePath, pdfPath);
        } else if (suffix.equals("ppt") || suffix.equals("pptx")) {
            return pptToPdf(inputFilePath, pdfPath);
            // return ppt2PDF(argInputFilePath, argPdfPath);
        }

        return false;
    }

    /**
     * word 转 pdf
     * @param wordPath 输入文件绝对路径
     * @param pdfPath 输出文件绝对路径
     * @return 转换是否成功，true 成功，false 不成功
     * @author xiaojf 2017/12/2 8:30
     */
    public static boolean wordToPDF(String wordPath, String pdfPath) {

        try {
            Dispatch docs = Dispatch.get(wordApp, "Documents").toDispatch();
            // long pdfStart = System.currentTimeMillis();
            Dispatch doc = Dispatch.invoke(docs, "Open", Dispatch.Method,
                    new Object[]{wordPath, new Variant(false), new Variant(true)}, new int[1]).toDispatch();

            deletePdf(pdfPath);

            Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[]{pdfPath, new Variant(WDFO_RMATPDF)},
                    new int[1]);
            // long pdfEnd = System.currentTimeMillis();
            if (null != doc) {
                Dispatch.call(doc, "Close", false);
            }
        } catch (Exception e) {
            e.printStackTrace();

        } /*
             * finally { wordApp.invoke("Quit"); }
             */
        return true;
    }

    /**
     * excel 转 pdf
     * @param inputFile 输入文件绝对路径
     * @param pdfFile 输出文件绝对路径
     * @return 转换是否成功，true 成功，false 不成功
     * @author xiaojf 2017/12/2 8:30
     */
    public static boolean excelToPdf(String inputFile, String pdfFile) {

        try {

            deletePdf(pdfFile);

            Dispatch excels = excelApp.getProperty("Workbooks").toDispatch();
            Dispatch excel = Dispatch.call(excels, "Open", inputFile, false, true).toDispatch();
            Dispatch.call(excel, "ExportAsFixedFormat", XLTYPE_PDF, pdfFile);
            Dispatch.call(excel, "Close", false);
        } catch (Exception e) {
            e.printStackTrace();
        } /*
             * finally { excelApp.invoke("Quit"); }
             */
        return true;
    }

    /**
     * ppt 转 pdf
     * @param inputFile 输入文件绝对路径
     * @param pdfFile 输出文件绝对路径
     * @return 转换是否成功，true 成功，false 不成功
     * @author xiaojf 2017/12/2 8:30
     */
    public static boolean pptToPdf(String inputFile, String pdfFile) {
        // ComThread.InitSTA(true);

        try {
            // app.setProperty("Visible", false);
            Dispatch ppts = pptApp.getProperty("Presentations").toDispatch();
            Dispatch ppt = Dispatch.call(ppts, "Open", inputFile, true, // ReadOnly
                    // false, // Untitled指定文件是否有标题
                    false// WithWindow指定文件是否可见
            ).toDispatch();
            Dispatch.invoke(ppt, "SaveAs", Dispatch.Method, new Object[]{pdfFile, new Variant(PPT_SAVEAS_PDF)},
                    new int[1]);
            Dispatch.call(ppt, "Close");
        } catch (Exception e) {
            e.printStackTrace();
        } /*
             * finally { pptApp.invoke("Quit"); }
             */

        return true;
    }

    /**
     * ppt 转 图片
     * @param inputFile 输入文件绝对路径
     * @param imgFile 输出文件绝对路径
     * @return 转换是否成功，true 成功，false 不成功
     * @author xiaojf 2017/12/2 8:30
     */
    public static boolean pptToImg(String inputFile, String imgFile) {
        // 打开word应用程序

        try {
            // 设置word不可见，office可能有限制
            // app.setProperty("Visible", false);
            // 获取word中国所打开的文档，返回Documents对象
            Dispatch files = ppApp.getProperty("Presentations").toDispatch();
            // 调用Documents对象中Open方法打开文档，并返回打开的文档对象Document
            Dispatch file = Dispatch.call(files, "open", inputFile, true, true, false).toDispatch();
            // 调用Document对象的SaveAs方法，将文档保存为pdf格式
            // Dispatch.call(doc, "ExportAsFixedFormat", outputFile,
            // PPT_TO_PDF);
            Dispatch.call(file, "SaveAs", imgFile, PPT_SAVEAS_JPG);
            // 关闭文档
            // Dispatch.call(file, "Close", false);
            Dispatch.call(file, "Close");
            // 关闭word应用程序
            // app.invoke("Quit", 0);
        } catch (Exception e) {
            e.printStackTrace();
        } /*
             * finally { ppApp.invoke("Quit"); }
             */

        return true;
    }

    /**
     * 获取文件扩展名
     * @param filePath
     * @author xiaojf 2017/12/2 8:35
     */
    public static String getFileSufix(String filePath) {
        int splitIndex = filePath.lastIndexOf(".");
        return filePath.substring(splitIndex + 1);
    }

    /**
     * 获取文件路径
     * @param filePath
     * @author xiaojf 2017/12/2 8:37
     */
    public static String getFilePath(String filePath) {
        int pathIndex = filePath.lastIndexOf("/");
        return filePath.substring(0, pathIndex);
    }

    /**
     *  如果目标文件存在，则删除
     *  @param pdfPath
     * @author xiaojf 2017/12/2 8:34
     */
    private static void deletePdf(String pdfPath) {
        File pdfFile = new File(pdfPath);
        if (pdfFile.exists()) {
            pdfFile.delete();
        }
    }

    public static void main(String[] args) {
        OfficeConverterUtil.wordToPDF("D:\\word2pdf\\1.doc",
                "D:\\word2pdf\\pdf\\" + UUID.randomUUID().toString() + ".doc.pdf");
        OfficeConverterUtil.wordToPDF("D:\\word2pdf\\1.docx",
                "D:\\word2pdf\\pdf\\" + UUID.randomUUID().toString() + ".docx.pdf");
        OfficeConverterUtil.pptToPdf("D:\\word2pdf\\1.ppt",
                "D:\\word2pdf\\pdf\\" + UUID.randomUUID().toString() + ".ppt.pdf");
        OfficeConverterUtil.pptToPdf("D:\\word2pdf\\1.pptx",
                "D:\\word2pdf\\pdf\\" + UUID.randomUUID().toString() + ".pptx.pdf");
        OfficeConverterUtil.wordToPDF("D:\\word2pdf\\1.rtf",
                "D:\\word2pdf\\pdf\\" + UUID.randomUUID().toString() + ".rtf.pdf");
        OfficeConverterUtil.wordToPDF("D:\\word2pdf\\1.txt",
                "D:\\word2pdf\\pdf\\" + UUID.randomUUID().toString() + ".txt.pdf");
        OfficeConverterUtil.excelToPdf("D:\\word2pdf\\1.xls",
                "D:\\word2pdf\\pdf\\" + UUID.randomUUID().toString() + ".xls.pdf");
        OfficeConverterUtil.excelToPdf("D:\\word2pdf\\1.xlsx",
                "D:\\word2pdf\\pdf\\" + UUID.randomUUID().toString() + ".xlsx.pdf");


        OfficeConverterUtil.pptToImg("D:\\word2pdf\\1.ppt",
                "D:\\word2pdf\\pdf\\" + UUID.randomUUID().toString() + ".ppt.jpg");


        wordApp.invoke("Quit");
        wordApp.safeRelease();
        excelApp.invoke("Quit");
        excelApp.safeRelease();
        pptApp.invoke("Quit");
        pptApp.safeRelease();
        ppApp.invoke("Quit");
        ppApp.safeRelease();

    }

}
